package com.rmfyzxfw.caseprocess.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;


/**
 * @author Lixx
 */
@Slf4j
public class RestTemplateUtil {


    private static RestTemplate getRestTemplate() {
        HttpComponentsClientHttpRequestFactory requestFactory = generateHttpRequestFactory();
        //5s
        requestFactory.setConnectTimeout(5000);
        requestFactory.setReadTimeout(5000);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        return restTemplate;
    }

    public static HttpComponentsClientHttpRequestFactory generateHttpRequestFactory() {
        TrustStrategy acceptingTrustStrategy = (x509Certificates, authType) -> true;
        SSLContext sslContext = null;
        try {
            sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (KeyManagementException e) {
            throw new RuntimeException(e);
        } catch (KeyStoreException e) {
            throw new RuntimeException(e);
        }
        SSLConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());

        HttpClientBuilder httpClientBuilder = HttpClients.custom();
        httpClientBuilder.setSSLSocketFactory(connectionSocketFactory);
        CloseableHttpClient httpClient = httpClientBuilder.build();
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setHttpClient(httpClient);
        return factory;
    }
    /**
     * GET请求
     * @param url 请求地址携带参数
     * @return
     */
    public static JSONObject get(String url){
        return get(url, null);
    }

    /**
     * get 表单
     * @param url
     * @param headerMap
     * @return
     */
    public static JSONObject get(String url, Map<String, String> headerMap){
        return exchange(url, HttpMethod.GET, headerMap);
    }

    /**
     * get 表单
     * @param url
     * @param headerMap
     * @return
     */
    public static JSONObject post(String url, Map<String, String> headerMap){
        return exchange(url, HttpMethod.POST, headerMap);
    }


    public static JSONObject exchange(String url, HttpMethod httpMethod, Map<String, String> headerMap){
        long timeMillis = System.currentTimeMillis();
        JSONObject resultJson = new JSONObject();
        try {
            RestTemplate restTemplate = getRestTemplate();
            HttpHeaders headers = new HttpHeaders();

            if(headerMap != null){
                for (String key : headerMap.keySet()){
                    headers.add(key, headerMap.get(key));
                }
            }
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            HttpEntity httpEntity = new HttpEntity<>("",headers);
            ResponseEntity<String> response = restTemplate.exchange(url, httpMethod, httpEntity, String.class);
            resultJson = JSON.parseObject(response.getBody());
            timeMillis = System.currentTimeMillis()-timeMillis;
            log.info("请求地址：{}, 返回数据：{}, 耗时：{}", url, resultJson, timeMillis);
            return resultJson;
        }catch (Exception e){
            timeMillis = System.currentTimeMillis()-timeMillis;
            log.error("请求地址：{}, 耗时：{}, 错误信息：{}", url, timeMillis, e);
            return null;
        }
    }


    /**
     * post json 请求
     * @param url
     * @return
     */
    public static JSONObject postJson(String url){
        return postJson(url, null, null);
    }

    /**
     * post json 请求
     * @param url
     * @return
     */
    public static JSONObject postJson(String url, JSONObject json){
        return postJson(url, json, null);
    }

    /**
     * post json 请求
     * @param url
     * @param json
     * @param headerMap
     * @return
     */
    public static JSONObject postJson(String url, JSONObject json, Map<String, String> headerMap){
        long timeMillis = System.currentTimeMillis();
        JSONObject resultJson = new JSONObject();
        try {
            RestTemplate restTemplate = getRestTemplate();
            HttpHeaders headers = new HttpHeaders();

            if(headerMap != null){
                for (String key : headerMap.keySet()){
                    headers.add(key, headerMap.get(key));
                }
            }
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity httpEntity = new HttpEntity<>(json, headers);
            ResponseEntity responseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
            resultJson = JSON.parseObject(responseEntity.getBody().toString());
            timeMillis = System.currentTimeMillis()-timeMillis;
            log.info("请求地址：{}, 入参：{}, 返回数据：{}, 耗时：{}", url, json, resultJson, timeMillis);
            return resultJson;
        }catch (Exception e){
            timeMillis = System.currentTimeMillis()-timeMillis;
            log.error("请求地址：{}, 入参：{}, 耗时：{}, 错误信息：{}", url, json, timeMillis, e);
            return null;
        }
    }

}
